﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;

namespace GitDC.Extensions
{
    public static class GitExtensions
    {
        public static string MakePackfile(this IEnumerable<string> lines)
            => string.Join("\n", lines.Select(d => $"{d.Length:x4}{d}").Append("0000"));

        public static IEnumerable<string> ReadPackfile(this Stream stream)
        {
            using (StreamReader reader = new StreamReader(stream))
            {
                string line;
                while (ReadPackfileLine(reader, out line) > 0)
                    yield return line;
            }
        }

        private static int ReadPackfileLine(StreamReader reader, out string line)
        {
            line = null;
            char[] lengthChars = new char[4];
            if (reader.Read(lengthChars, 0, 4) < 4)
                return -1;

            int lineLength;
            if (!int.TryParse(new string(lengthChars), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out lineLength))
                return -1;

            char[] lineChars = new char[lineLength];
            if (reader.Read(lineChars, 0, lineLength) < lineLength)
                return -1;

            line = new string(lineChars);
            reader.ReadLine();
            return lineLength;
        }

        public static IEnumerable<T> TraverseTree<T>(this T root, Func<T, IEnumerable<T>> childSelector)
        {
            Stack<T> nodes = new Stack<T>(new[] { root });
            while (nodes.Count > 0)
            {
                T node = nodes.Pop();
                yield return node;

                foreach (T child in childSelector(node))
                    nodes.Push(child);
            }
        }
    }
}
